# -*- coding: utf-8 -*-
# Author: lkm
# date: 2022/3/9 17:35

import re
from traceback import format_exc
from pandas import read_csv, set_option, DataFrame
from sklearn.preprocessing import OneHotEncoder

set_option("display.width", 10000)
set_option("display.max_rows", None)
set_option("display.max_columns", None)


class FeatureEngineering(object):
    def __init__(self, filename: str, resFrame: DataFrame = DataFrame()):
        try:
            data = read_csv(filename)

            # 独热编码
            ontHot_feature_names = ["gender", "Partner", "Dependents", "PhoneService", "MultipleLines",
                                    "InternetService", "OnlineSecurity", "OnlineBackup", "DeviceProtection",
                                    "TechSupport", "StreamingTV", "StreamingMovies", "Contract",
                                    "PaperlessBilling", "PaymentMethod", "Churn"]
            onehot_dt = self.one_hot_transform(data, ontHot_feature_names)

            # 合并数据
            data.drop(ontHot_feature_names, axis=1, inplace=True)
            data = data.join(onehot_dt)

            # 独热编码n-1
            drop_feature_names = ["gender_Female", "Partner_No", "Dependents_No", "PhoneService_No", "MultipleLines_No",
                                  "InternetService_No", "OnlineSecurity_No", "OnlineBackup_No", "DeviceProtection_No",
                                  "TechSupport_No", "StreamingTV_No", "StreamingMovies_No", "Contract_Month-to-month",
                                  "PaperlessBilling_No", "PaymentMethod_Bank transfer (automatic)", "Churn_No"]
            data.drop(drop_feature_names, axis=1, inplace=True)

            # 类型转换，填充缺失值
            data["TotalCharges"] = data["TotalCharges"].replace(" ", "0")
            data["TotalCharges"] = data["TotalCharges"].astype(float)

            self.resFrame = data
        except FileNotFoundError:
            print(format_exc())
            self.resFrame = resFrame

    @staticmethod
    def one_hot_transform(df: DataFrame, fields: list) -> DataFrame:
        """
        Feature transform values
        @param df: DataFrame
        @param fields: String
        @return: DataFrame
        """
        col_names = dict()  # 创建空字典
        for ind, val in enumerate(fields):  # 遍历字段名称
            col_names["x{}_".format(str(ind))] = val + "_"  # 逐个将元素添加到字典中

        # 构建独热编码模型
        oneHot = OneHotEncoder()
        oneHot.fit(df[fields])  # 训练模型
        feature_names = oneHot.get_feature_names().tolist()  # 输出特征名称

        feature_names_sub = list()  # 定义空列表进行存储处理后的特征名称
        pattern = re.compile(r"{}".format('|'.join([re.escape(x) for x in col_names])))  # 正则匹配规则
        for feature_name in feature_names:  # 遍历模型训练后的特征名称
            feature_names_sub.append(pattern.sub(lambda m: col_names[re.escape(m.group(0))], feature_name))  # 添加

        # 组装数据帧
        oneHotFrame = DataFrame(oneHot.transform(df[fields]).toarray(), columns=feature_names_sub)

        return oneHotFrame
